/*
 * @Author: wuqingchun
 * @Date: 2024-07-09 21:08:46
 * @Description: 
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-07-10 11:05:24
 */
#include <cstdio>
#include <cerrno>
#include <cstring>

#include <time.h>

#include "mp_epoller.h"


CMPEpoller::CMPEpoller()
{
}

int32_t CMPEpoller::Create(const char* pcName, size_t ulSize)
{
    if (pcName == nullptr || pcName[0] == '\0')
    {
        printf("Invalid parameter\n");

        return -1;
    }

    m_pstSem = sem_open(pcName, O_CREAT|O_RDWR, 0666, 0);
    if (m_pstSem == nullptr)
    {
        printf("sem_open error, %s\n", strerror(errno));

        return -1;
    }

    return 0;
}

int32_t CMPEpoller::Wait(MP_EP_OBJECT* pstObjects, uint32_t uiMaxObject, int32_t iTimeout)
{
    int32_t iResult = -1;

    if (m_pstSem == nullptr)
    {
        return iResult;
    }

    if (iTimeout == -1)
    {
        do
        {
            iResult = sem_wait(m_pstSem);
        } while (iResult == -1 && errno == EINTR);
    }
    else
    {
        struct timespec stTS;
        clock_gettime(CLOCK_REALTIME, &stTS);
        stTS.tv_nsec += (long)iTimeout * 1000;

        if (stTS.tv_nsec >= 1000000000)
        {
            stTS.tv_sec++;
            stTS.tv_nsec -= 1000000000;
        }
        
        do
        {
            iResult = sem_timedwait(m_pstSem, &stTS);
        } while (iResult == -1 && errno == EINTR);
    }

    if (iResult == -1)
    {
        if (errno == ETIMEDOUT)
        {
            iResult = 0;
        }
    }
    else
    {
        iResult = 1;
    }

    // 拷贝数据
    return iResult;
}

int32_t CMPEpoller::Post(uint32_t uiObjectID)
{
    if (m_pstSem != nullptr)
    {
        return sem_post(m_pstSem);
    }

    return -1;
}

void CMPEpoller::Close()
{
    if (m_pstSem == nullptr)
    {
        sem_close(m_pstSem);
        m_pstSem = nullptr;
    }
}